﻿// -----------------------------------------------------------------------
// <copyright file="WebCacheManager.cs" company="EPAM Systems">
////Copyright (c) EPAM Systems, 2012. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------

// TODO: check naming design for readonly fields.
namespace MBOP.Domain.Managers
{
	#region Usings

	using System;
	using System.Configuration;
	using System.Web;
	using System.Web.Caching;

	using MBOP.Configuration.ConfigElements;
	using MBOP.Core.Interfaces.Managers;

	#endregion

	/// <summary>
	/// The <see cref="ICacheManager"/> implementer
	/// which allows to use web server's cache.
	/// </summary>
	public class WebCacheManager : ICacheManager
	{
		#region Private Fields

		/// <summary>
		/// Represents the web cache.
		/// </summary>
		private Cache _webCache;

		/// <summary>
		/// Represents the cache config. 
		/// </summary>
		private CachingConfigurationSection _cachingConfig;

		#endregion

		#region Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="WebCacheManager"/> class, which use the memory server cache.
		/// </summary>
		public WebCacheManager()
		{
			this._cachingConfig = (CachingConfigurationSection)ConfigurationManager.GetSection(CachingConfigurationSection.CACHING_CONFIGURATION_SECTION_NAME);
			this._webCache = HttpContext.Current.Cache;
		}

		#endregion

		#region ICacheManager Implementation

		#region Methods

		/// <summary>
		/// Adds the item to cache.
		/// </summary>
		/// <param name="key">The key.</param>
		/// <param name="item">The item.</param>
		/// <param name="isSliding">Defines storing type.</param>
		/// <param name="expiration">The Expiration interval</param>
		public void Add(string key, object item, bool isSliding, TimeSpan expiration)
		{
			if (!string.IsNullOrEmpty(key))
			{
				DateTime absoluteExpiration;
				TimeSpan slidingExpiration;

				if (isSliding)
				{
					absoluteExpiration = DateTime.MaxValue;
					slidingExpiration = expiration;
				}
				else
				{
					absoluteExpiration = DateTime.Now.Add(expiration);
					slidingExpiration = TimeSpan.Zero;
				}

				this._webCache.Insert(key, item, null, absoluteExpiration, slidingExpiration);
			}
		}

		/// <summary>
		/// Adds the item to cache.
		/// </summary>
		/// <param name="key">The key.</param>
		/// <param name="item">The item.</param>
		/// <param name="isSliding">Defines storing type.</param>
		public void Add(string key, object item, bool isSliding)
		{
			this.Add(key, item, isSliding, TimeSpan.FromSeconds(this._cachingConfig.CacheManager.DefaultTimeInCacheSeconds));
		}

		/// <summary>
		/// Gets the item from cache.
		/// </summary>
		/// <typeparam name="T">The type of the item.</typeparam>
		/// <param name="key">The key.</param>
		/// <returns>The item.</returns>
		public T GetItem<T>(string key) where T : class
		{
			T item = null;

			if (!string.IsNullOrEmpty(key))
			{
				item = this._webCache.Get(key) as T;
			}

			return item;
		}

		/// <summary>
		/// Checks that item in cache with specified key.
		/// </summary>
		/// <param name="key">The key.</param>
		/// <returns>The result of checking operation.</returns>
		public bool IsInCache(string key)
		{
			bool isInCache = false;

			if (!string.IsNullOrEmpty(key))
			{
				if (this._webCache[key] != null)
				{
					isInCache = true;
				}
			}

			return isInCache;
		}

		#endregion

		#endregion
	}
}
